package com.zsy.petshop_01.service.impl;

import io.minio.*;
import io.minio.errors.MinioException;
import io.minio.messages.Part;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

@Service
public class MinIOService {
    @Value("${minio.bucketName}")
    private String bucketName;
    @Value("${minio.endpoint}")
    private String endpoint;

    @Autowired
    private MinioClient minioClient;

    private static final int PART_SIZE = 5 * 1024 * 1024; // 每个分片的大小为 5MB

    public String uploadFile(MultipartFile file) throws Exception {
        // 生成唯一的文件名
        String fileName = UUID.randomUUID() + "-" + file.getOriginalFilename();

        try (InputStream inputStream = file.getInputStream()) {
            // 上传文件到 MinIO
            PutObjectArgs putObjectArgs = PutObjectArgs.builder()
                    .bucket(bucketName)
                    .object(fileName)
                    .stream(inputStream, file.getSize(), -1)
                    .contentType(file.getContentType())
                    .build();
            minioClient.putObject(putObjectArgs);
        } catch (IOException e) {
            throw new Exception("文件上传失败", e);
        }

        // 构造文件的公共访问 URL
        return endpoint + "/" + bucketName + "/" + fileName;
    }

    public String uploadFileInParts(MultipartFile file, String objectName) throws IOException, NoSuchAlgorithmException, InvalidKeyException {
        try {
            long fileSize = file.getSize();
            long offset = 0;
            int partNumber = 1;
            List<ComposeSource> sources = new ArrayList<>();

            while (offset < fileSize) {
                long partSize = Math.min(PART_SIZE, fileSize - offset);
                String partObjectName = objectName + ".part" + partNumber;
                ObjectWriteResponse response = minioClient.putObject(
                        PutObjectArgs.builder()
                                .bucket(bucketName)
                                .object(partObjectName)
                                .stream(file.getInputStream(), partSize, -1)
                                .build()
                );
                System.out.println("Part " + partNumber + " uploaded: " + response.etag());
                sources.add(ComposeSource.builder()
                        .bucket(bucketName)
                        .object(partObjectName)
                        .build());
                offset += partSize;
                partNumber++;
            }

            // 合并分片
            ComposeObjectArgs composeObjectArgs = ComposeObjectArgs.builder()
                    .bucket(bucketName)
                    .object(objectName)
                    .sources(sources)
                    .build();
            minioClient.composeObject(composeObjectArgs);

            // 删除临时分片文件
            for (ComposeSource source : sources) {
                minioClient.removeObject(io.minio.RemoveObjectArgs.builder()
                        .bucket(bucketName)
                        .object(source.object())
                        .build());
            }

        } catch (MinioException e) {
            System.err.println("Error occurred: " + e);
        }
        // 构造文件的公共访问 URL
        return endpoint + "/" + bucketName + "/" + objectName;
    }
}
